package com.uiotsoft.small.app.sampler.simple;

import com.uiotsoft.small.mqtt.MqttClientOld;
import com.uiotsoft.util.encrypt.MD5Utils;
import com.uiotsoft.util.encrypt.small.SignUtil;
import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.threads.JMeterContextService;
import org.apache.jmeter.threads.JMeterVariables;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class AppConnectSampler extends AbstractJavaSamplerClient {
    private volatile MqttClientOld clientOld;
    private static final Logger log = LoggerFactory.getLogger(AppConnectSampler.class);
    private String subTopic;
    private MqttConnectOptions options;

    public Arguments getDefaultParameters() {
        Arguments params = new Arguments();
        params.addArgument("appKey", "${appKey}");
        params.addArgument("appSecret", "${appSecret}");
        params.addArgument("mqttUrl", "tcp://${hostIp}:1883");
        params.addArgument("clientId", "uiot_app-${si}");
        params.addArgument("username", "${appKey}|${si}|uiot_app|${__time(,)}");
        params.addArgument("si", "${si}");
        params.addArgument("willTopic", "host/app/");
        params.addArgument("willData", "");
        return params;
    }

    private void setupValues(JavaSamplerContext context) {
        String appKey = context.getParameter("appKey");
        String appSecret = context.getParameter("appSecret");
        String mqttUrl = context.getParameter("mqttUrl");
        String clientId = context.getParameter("clientId");
        String username = context.getParameter("username");
        String si = context.getParameter("si");
        String willTopic = context.getParameter("willTopic");
        String willData = context.getParameter("willData");

        subTopic = "app/+/+/" + si + "/+";
        String password = MD5Utils.MD5Encoding(username + appSecret, "");
        clientOld = new MqttClientOld(mqttUrl, clientId);
        log.debug("client 初始化成功：{}",clientId);
        clientOld.setAppKey(appKey);
        clientOld.setAppSecret(appSecret);
        //配置options
        options = new MqttConnectOptions();
        options.setMqttVersion(3);
        options.setConnectionTimeout(10);
        options.setMaxReconnectDelay(5);
        options.setKeepAliveInterval(30);
        options.setCleanSession(true);
        options.setAutomaticReconnect(true);
        options.setUserName(username);
        options.setPassword(password.toCharArray());
        //设置遗嘱
        if (willTopic != null && !willTopic.equals("")){
            if (appSecret != null && !appSecret.equals("")){
                byte[] message = SignUtil.getPublishMessage(willData, appKey,appSecret);
                options.setWill(willTopic, message, 0, true);
            }else {
                log.error("appSecret 为空！");
            }
        }
    }

    @Override
    public SampleResult runTest(JavaSamplerContext javaSamplerContext) {
        setupValues(javaSamplerContext);
        JMeterVariables vars = JMeterContextService.getContext().getVariables();
        SampleResult results = new SampleResult();
        results.setDataEncoding("UTF-8");
        results.sampleStart();
        try {
            clientOld.setMqttClient(options, null);
            clientOld.subscribe(subTopic);
            results.sampleEnd();
            if (clientOld.getMqttClient().isConnected()){
                vars.putObject("clientOld", clientOld);
                results.setSuccessful(true);
                results.setResponseData("Successful", "UTF-8");
                results.setResponseMessage("Connection established successfully.");
                results.setResponseCodeOK();
            }else {
                results.setSuccessful(false);
                results.setResponseData("Connect failed", "UTF-8");
                results.setResponseMessage("Failed to establish Connection.");
                results.setResponseCode("501");
            }
        } catch (MqttException e) {
            if (results.getEndTime() == 0) results.sampleEnd();
            log.info("Failed to establish Connection :{}", e.getMessage());
            results.setSuccessful(false);
            results.setResponseData("Connect failed with exception", "UTF-8");
            results.setResponseMessage("Failed to establish Connection.");
            results.setResponseCode("502");
        }
        return results;
    }

}
